package typeconvertest

import (
	"fmt"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
)

var TypeConvtest = new(typeconvtestApi)

type typeconvtestApi struct {
}

func (p *typeconvtestApi) Test1() {
	i := 123.456
	fmt.Printf("%10s %v\n", "Int:", gconv.Int(i))
	fmt.Printf("%10s %v\n", "Int8:", gconv.Int8(i))
	fmt.Printf("%10s %v\n", "Int16:", gconv.Int16(i))
	fmt.Printf("%10s %v\n", "Int32:", gconv.Int32(i))
	fmt.Printf("%10s %v\n", "Int64:", gconv.Int64(i))
	fmt.Printf("%10s %v\n", "Uint:", gconv.Uint(i))
	fmt.Printf("%10s %v\n", "Uint8:", gconv.Uint8(i))
	fmt.Printf("%10s %v\n", "Uint16:", gconv.Uint16(i))
	fmt.Printf("%10s %v\n", "Uint32:", gconv.Uint32(i))
	fmt.Printf("%10s %v\n", "Uint64:", gconv.Uint64(i))
	fmt.Printf("%10s %v\n", "Float32:", gconv.Float32(i))
	fmt.Printf("%10s %v\n", "Float64:", gconv.Float64(i))
	fmt.Printf("%10s %v\n", "Bool:", gconv.Bool(i))
	fmt.Printf("%10s %v\n", "String:", gconv.String(i))
	fmt.Printf("%10s %v\n", "Bytes:", gconv.Bytes(i))
	fmt.Printf("%10s %v\n", "Strings:", gconv.Strings(i))
	fmt.Printf("%10s %v\n", "Ints:", gconv.Ints(i))
	fmt.Printf("%10s %v\n", "Floats:", gconv.Floats(i))
	fmt.Printf("%10s %v\n", "Interfaces:", gconv.Interfaces(i))
}

func (p *typeconvtestApi) Test2() {
	type User struct {
		Uid  int    `c:"uid"`
		Name string `c:"name"`
	}
	g.Dump(gconv.Map(User{Uid: 1, Name: "xxx"}))
	g.Dump(gconv.Map(&User{Uid: 1, Name: "xxx"}))
	g.Dump(gconv.Map(map[int]int{
		100: 1000,
	}))
}

func (p *typeconvtestApi) Test3() {
	type User struct {
		Uid      int
		Name     string `c:"-"`
		NickName string `c:"nickname,omitempty"`
		Pass1    string `c:"password1"`
		Pass2    string `c:"password2"`
	}
	user := User{
		Uid:   100,
		Name:  "xxx",
		Pass1: "sss",
		Pass2: "xxxx",
	}
	g.Dump(gconv.Map(user))
}

func (p *typeconvtestApi) Test4() {
	type User struct {
		Id   int    `c:"uid"`
		Name string `my-tag:"nick-name" c:"name"`
	}
	user := User{
		Id:   1,
		Name: "sss",
	}
	g.Dump(gconv.Map(user, "my-tag"))
}

func (p *typeconvtestApi) Test5() {
	type Base struct {
		Id   int    `c:"id"`
		Date string `c:"date"`
	}
	type User struct {
		Base     `c:"base"`
		Passport string `c:"passport"`
		Password string `c:"password"`
		Nickname string `c:"nickname"`
	}
	user := new(User)
	user.Id = 1
	user.Date = "xxx"
	user.Nickname = "11"
	user.Passport = "ss"
	user.Password = "123"
	g.Dump(gconv.MapDeep(user))
}

func (p *typeconvtestApi) Test6() {
	type User struct {
		Uid  int
		Name string
	}
	params := g.Map{
		"uid":  1,
		"name": "xxx",
	}
	var user *User
	if err := gconv.Struct(params, &user); err != nil {
		panic(err)
	}
	g.Dump(user)
}

func (p *typeconvtestApi) Test7() {
	type Ids struct {
		Id  int `json:"id"`
		Uid int `json:"uid"`
	}
	type Base struct {
		Ids
		CreateTime string `json:"create_time"`
	}
	type User struct {
		Base
		Passport string `json:"passport"`
		Password string `json:"password"`
		Nickname string `json:"nickname"`
	}
	data := g.Map{
		"id":          1,
		"uid":         100,
		"passport":    "john",
		"password":    "123456",
		"nickname":    "John",
		"create_time": "2019",
	}
	user := new(User)
	gconv.StructDeep(data, user)
	g.Dump(user)
}

func (p *typeconvtestApi) Test8() {
	type User struct {
		Uid      int
		Name     string
		Site_Url string
		NickName string
		Pass1    string `gconv:"password1"`
		Pass2    string `gconv:"password2"`
	}
	user := (*User)(nil)

	// 使用默认映射规则绑定属性值到对象
	user = new(User)
	params1 := g.Map{
		"uid":       1,
		"Name":      "john",
		"siteurl":   "https://goframe.org",
		"nick_name": "johng",
		"PASS1":     "123",
		"PASS2":     "456",
	}
	if err := gconv.Struct(params1, user); err == nil {
		g.Dump(user)
	}

	// 使用struct tag映射绑定属性值到对象
	user = new(User)
	params2 := g.Map{
		"uid":       2,
		"name":      "smith",
		"site-url":  "https://goframe.org",
		"nick name": "johng",
		"password1": "111",
		"password2": "222",
	}
	if err := gconv.Struct(params2, user); err == nil {
		g.Dump(user)
	}
}

func (p *typeconvtestApi) Test9() {
	type Score struct {
		Name   string
		Result int
	}
	type User1 struct {
		Scores Score
	}
	type User2 struct {
		Scores *Score
	}

	user1 := new(User1)
	user2 := new(User2)
	scores := g.Map{
		"Scores": g.Map{
			"Name":   "john",
			"Result": 100,
		},
	}

	if err := gconv.Struct(scores, user1); err != nil {
		fmt.Println(err)
	} else {
		g.Dump(user1)
	}
	if err := gconv.Struct(scores, user2); err != nil {
		fmt.Println(err)
	} else {
		g.Dump(user2)
	}
}

func (p *typeconvtestApi) Test10() {
	var p1, p2 *Pkg

	// Create a demo pkg as p1.
	p1 = NewPkg([]byte("123"))
	fmt.Println(p1)

	// Convert bytes from p1 to p2 using gconv.Struct.
	err := gconv.Struct(p1.Marshal(), &p2)
	if err != nil {
		panic(err)
	}
	fmt.Println(p2)
}
